package com.stox.repository.file;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.stox.manager.CountryManager;
import com.stox.manager.ExchangeManager;
import com.stox.model.Country;
import com.stox.model.Exchange;
import com.stox.model.Scrip;
import com.stox.repository.ScripRepository;

@Component
public class ScripFileRepository 
			extends AbstractFileRepository<Scrip, String>
			implements ScripRepository, InitializingBean{

	@Autowired
	private CountryManager countryManager;
	
	@Autowired 
	private ExchangeManager exchangeManager;

	private final Map<String, Map<String, Scrip>> cache = 
			new HashMap<String, Map<String, Scrip>>();

	public void afterPropertiesSet() throws Exception {
		for(Country country : countryManager.findAll()){
			for(Exchange exchange : exchangeManager.findByCountryCode(country.getCode())){
				createPartition(exchange.getCode());
				final Map<String, Scrip> map = new HashMap<String, Scrip>();
				cache.put(exchange.getCode(), map);
				iterate(new EntityIterator<Scrip>(){
					public boolean shouldContinue(Scrip scrip) {
						map.put(scrip.getCode(), scrip);
						return true;
					}
				}, exchange.getCode());
			}
		}
	}

	@Override
	protected Scrip deserialize(String text, String exchangeCode) {
		return new Scrip(exchangeCode, text);
	}

	@Override
	protected String serialize(Scrip scrip) {
		return scrip.toString();
	}

	@Override
	protected String getFilePath(String exchangeCode) {
		Exchange exchange = exchangeManager.findOne(exchangeCode);
		return getFilebasePath() + File.separator + exchange.getCountryCode()
				+ File.separator + exchange.getCode() + File.separator + "scrip.csv";
	}

	public List<Scrip> findByExchangeCode(String exchangeCode) {
		return new ArrayList<Scrip>(cache.get(exchangeCode).values());
	}

	public Scrip findOne(String scripCode) {
		for(Map<String, Scrip> map : cache.values()){
			for(Scrip scrip : map.values()){
				if(scripCode.equalsIgnoreCase(scrip.getCode())){
					return scrip;
				}
			}
		}
		return null;
	}
	
	public boolean exists(String scripCode) {
		for(Map<String, Scrip> map : cache.values()){
			if(map.containsKey(scripCode)){
				return true;
			}
		}
		return false;
	}

	public Scrip save(Scrip scrip) {
		if(!exists(scrip.getCode())){
			Map<String, Scrip> map = cache.get(scrip.getExchangeCode());
			if(null == map){
				map = new HashMap<String, Scrip>();
				cache.put(scrip.getExchangeCode(), map);
			}
			map.put(scrip.getCode(), scrip);
			
			return save(scrip, scrip.getExchangeCode());
		}
		return scrip;
	}

}
